package com.ikingtech.platform.service.sms.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.log.embedded.annotation.OperationLog;
import com.ikingtech.framework.sdk.sms.api.SmsApi;
import com.ikingtech.framework.sdk.sms.embedded.SmsConfig;
import com.ikingtech.framework.sdk.sms.embedded.SmsRequestBuilder;
import com.ikingtech.framework.sdk.sms.embedded.SmsSendArgs;
import com.ikingtech.framework.sdk.sms.model.SmsDTO;
import com.ikingtech.framework.sdk.sms.model.SmsQueryParamDTO;
import com.ikingtech.framework.sdk.sms.model.SmsSendMessageParamDTO;
import com.ikingtech.framework.sdk.sms.model.SmsTemplateDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.sms.entity.SmsDO;
import com.ikingtech.platform.service.sms.exception.SmsExceptionInfo;
import com.ikingtech.platform.service.sms.service.SmsRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
@ApiController(value = "/sms", name = "短信平台管理", description = "短信平台管理")
public class SmsController implements SmsApi {

    private final SmsRepository repo;

    private final SmsRequestBuilder smsRequestBuilder;

    /**
     * 添加短信平台
     *
     * @param sms 短信平台DTO对象
     * @return 返回添加结果
     */
    @Override
    @OperationLog(value = "添加短信平台", dataId = "#_res.getData()")
    @Transactional(rollbackFor = Exception.class)
    public R<String> add(SmsDTO sms) {
        // 将短信平台DTO对象转换为短信平台DO对象
        SmsDO entity = Tools.Bean.copy(sms, SmsDO.class);
        // 生成唯一ID
        entity.setId(Tools.Id.uuid());
        entity.setTenantCode(Me.tenantCode());
        // 保存短信平台DO对象到数据库
        this.repo.save(entity);
        // 返回添加结果
        return R.ok(entity.getId());
    }

    /**
     * 删除短信平台
     *
     * @param id 短信平台id
     * @return 删除结果
     */
    @Override
    @OperationLog(value = "删除短信平台")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> delete(String id) {
        // 通过id删除数据
        this.repo.removeById(id);
        // 返回删除成功的结果
        return R.ok();
    }

    /**
     * 更新短信平台
     *
     * @param sms 短信平台信息
     * @return 更新结果
     */
    @Override
    @OperationLog(value = "更新短信平台")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> update(SmsDTO sms) {
        // 检查短信平台是否存在
        if (!this.repo.exists(Wrappers.<SmsDO>lambdaQuery().eq(SmsDO::getId, sms.getId()))) {
            throw new FrameworkException(SmsExceptionInfo.SMS_NOT_FOUND);
        }

        // 更新短信平台
        this.repo.updateById(Tools.Bean.copy(sms, SmsDO.class));
        return R.ok();
    }

    /**
     * 分页查询短信列表
     *
     * @param queryParam 查询参数
     * @return 分页结果
     */
    @Override
    public R<List<SmsDTO>> page(SmsQueryParamDTO queryParam) {
        // 调用数据库操作层的分页查询方法，将查询结果转换为SmsDTO对象列表
        return R.ok(PageResult.build(this.repo.page(new Page<>(queryParam.getPage(), queryParam.getRows()), Wrappers.<SmsDO>lambdaQuery()
                .eq(Tools.Str.isNotBlank(queryParam.getCode()), SmsDO::getCode, queryParam.getCode())
                .like(Tools.Str.isNotBlank(queryParam.getName()), SmsDO::getName, queryParam.getName())
                .eq(Tools.Str.isNotBlank(queryParam.getAppId()), SmsDO::getAppId, queryParam.getAppId())
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), SmsDO::getTenantCode, Me.tenantCode()))).convert(entity -> Tools.Bean.copy(entity, SmsDTO.class)));
    }

    /**
     * 获取所有短信平台
     *
     * @return 短信平台列表
     */
    @Override
    public R<List<SmsDTO>> all() {
        // 将repo中的对象转换为SmsDTO对象
        return R.ok(Tools.Coll.convertList(this.repo.list(Wrappers.<SmsDO>lambdaQuery().eq(Tools.Str.isNotBlank(Me.tenantCode()), SmsDO::getTenantCode, Me.tenantCode())), entity -> Tools.Bean.copy(entity, SmsDTO.class)));
    }

    /**
     * 获取短信平台详情
     *
     * @param id 短信平台ID
     * @return 返回短信平台详情
     */
    @Override
    public R<SmsDTO> detail(String id) {
        // 通过ID获取短信实体
        SmsDO entity = this.repo.getById(id);
        // 如果短信实体为空，则抛出异常
        if (null == entity) {
            throw new FrameworkException(SmsExceptionInfo.SMS_NOT_FOUND);
        }
        // 将短信实体转换为短信DTO并返回
        return R.ok(Tools.Bean.copy(entity, SmsDTO.class));
    }

    /**
     * 发送短信
     *
     * @param sendMessageParam 发送短信参数
     * @return 返回结果
     */
    @Override
    @OperationLog(value = "发送短信")
    public R<Object> send(SmsSendMessageParamDTO sendMessageParam) {
        // 构建短信请求
        this.smsRequestBuilder.build(this.loadConfig(sendMessageParam.getSmsId()))
                .send(SmsSendArgs.builder()
                        .templateId(sendMessageParam.getTemplateId())
                        .content(sendMessageParam.getContent())
                        .params(sendMessageParam.getParams())
                        .phone(sendMessageParam.getPhone())
                        .build());
        // 返回发送结果
        return R.ok();
    }

    /**
     * 获取短信平台模板列表
     *
     * @param smsId 短信平台ID
     * @return 返回短信平台模板列表
     */
    @Override
    public R<List<SmsTemplateDTO>> listTemplate(String smsId) {
        return R.ok(Tools.Coll.convertList(this.smsRequestBuilder.build(this.loadConfig(smsId)).listTemplate(), templateInfo -> {
            SmsTemplateDTO template = new SmsTemplateDTO();
            template.setId(templateInfo.getTemplateId());
            template.setName(templateInfo.getTemplateName());
            template.setSmsId(smsId);
            template.setStatus(templateInfo.getStatus());
            template.setStatusName(template.getStatus().description);
            template.setTitle(templateInfo.getTemplateName());
            template.setContent(templateInfo.getContent());
            template.setParams(templateInfo.getParams());
            return template;
        }));
    }

    /**
     * 加载短信平台配置
     *
     * @param smsId 短信平台ID
     * @return 短信平台配置对象
     */
    private SmsConfig loadConfig(String smsId) {
        // 通过ID获取短信实体
        SmsDO entity = this.repo.getById(smsId);
        // 如果实体为空，则从属性文件中读取短信配置
        if (null == entity) {
            throw new FrameworkException("smsNotFound");
        }
        // 如果实体不为空，则将实体转换为短信配置对象
        return Tools.Bean.copy(entity, SmsConfig.class);
    }
}
